﻿// 定义cards类，是卡牌的集合类
// 作用于手牌、所有牌、三张底牌等
#include "cards.h"

#include <QDebug>
#include <QRandomGenerator>

Cards::Cards() {}

Cards::Cards(const Card& card) { add(card); }

void Cards::add(const Card& card) { m_cards.insert(card); }

void Cards::add(const Cards& cards) {
    m_cards.unite(cards.m_cards);  //合并Qset操作，存储到调用者中
}

void Cards::add(const QVector<Cards>& cards) {
    for (int i = 0; i < cards.count(); ++i) {
        add(cards.at(i));
    }
}

Cards& Cards::operator<<(const Card& card) {
    add(card);
    return *this;
}

Cards& Cards::operator<<(const Cards& cards) {
    add(cards);
    return *this;
}

void Cards::remove(const Card& card) { m_cards.remove(card); }

void Cards::remove(const Cards& cards) {
    m_cards.subtract(cards.m_cards);  //差集Qset操作，对原Qset 删除相同的元素
}

void Cards::remove(const QVector<Cards>& cards) {
    for (int i = 0; i < cards.size(); ++i) {
        remove(cards.at(i));
    }
}

int Cards::cardCount() { return m_cards.size(); }

bool Cards::isEmpty() { return m_cards.isEmpty(); }

void Cards::clear() { m_cards.clear(); }

Card::CardPoint Cards::maxPoint() {
    Card::CardPoint max =
        Card::Card_Begin;  //类内定义的枚举类型可以使用“静态”的方法引用
    if (!m_cards.isEmpty()) {
        for (auto it = m_cards.begin(); it != m_cards.end(); ++it) {
            if (it->point() > max) {
                max = it->point();  //获取最大值
            }
        }
    }
    return max;  //容器为空，返回Card_Begin
}

Card::CardPoint Cards::minPoint() {
    Card::CardPoint min = Card::Card_End;
    if (!m_cards.isEmpty()) {
        for (auto it = m_cards.begin(); it != m_cards.end(); ++it) {
            if (it->point() < min) {
                min = it->point();  //获取最小值
            }
        }
    }
    return min;  //容器为空 返回Card_End
}

int Cards::pointCount(Card::CardPoint point)  //某一点数的个数
{
    int count = 0;
    for (auto it = m_cards.begin(); it != m_cards.end(); ++it) {
        if (it->point() == point) {
            count++;
        }
    }
    return count;
}

bool Cards::contains(const Card& card) { return m_cards.contains(card); }

bool Cards::contains(const Cards& cards) {
    return m_cards.contains(cards.m_cards);
}

Card Cards::takeRandomCard() {
    // 生成一个随机数
    int num = QRandomGenerator::global()->bounded(m_cards.size());  //随机数0~max-1，左闭右开，可使用double
    QSet<Card>::const_iterator it = m_cards.constBegin();  //只读迭代器
    for (int i = 0; i < num; ++i, ++it)  //循环递增到指定的位置 后移num
        ;
    Card card = *it;    //获取迭代器指向的牌的拷贝
    m_cards.erase(it);  //删除该牌
    return card;        //返回拷贝
}

CardList Cards::toCardList(SortType type) {
    CardList list;
    for (auto it = m_cards.begin(); it != m_cards.end(); ++it) {
        list << *it;  //传入list
    }
    if (type == Asc) {  //升序
        //参数3 是一个返回类型为bool的回调函数 ，指定排序方式，左右符合
        //不换(true)，左右不符 换(false)
        std::sort(list.begin(), list.end(), lessSort);
    }
    else if (type == Desc) {  //降序
        std::sort(list.begin(), list.end(), greaterSort);
    }
    return list;
}

void Cards::printAllCardInfo() {
    QString text;
    char pts[] = "JQKA2";
    for (auto it = m_cards.begin(); it != m_cards.end(); ++it) {
        QString msg;
        Card::CardPoint pt = it->point();
        Card::CardSuit suit = it->suit();
        if (suit == Card::CardSuit::Club) {
            msg = "梅花";
        }
        else if (suit == Card::CardSuit::Diamond) {
            msg = "方片";
        }
        else if (suit == Card::CardSuit::Heart) {
            msg = "红桃";
        }
        else {
            msg = "黑桃";
        }
        if (pt >= Card::Card_3 && pt <= Card::Card_10) {
            msg = QString("%1%2").arg(msg).arg(pt + 2);
        }
        else if (pt >= Card::Card_J && pt <= Card::Card_2) {
            msg = QString("%1%2").arg(msg).arg(pts[pt - Card::Card_J]);
        }
        if (pt == Card::Card_BJ) {
            msg = "Big Joker";
        }
        if (pt == Card::Card_SJ) {
            msg = "Small Joker";
        }
        msg += "  ";
        text += msg;
    }
    qDebug() << text;
}
